#!/bin/bash -eu
#
# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

source /opt/c2d/c2d-utils || exit 1

readonly wordpress_password="$(get_attribute_value "wordpress-mysql-password")"
readonly deployment="$(get_attribute_value "deployment")"

readonly runtime_config="$(get_attribute_value "rtc-name")"
readonly hostname="$(get_hostname)"

readonly database_ip="$(get_attribute_value "cloudsql-connection-ip")"

readonly wp_admin_email="$(get_attribute_value "wordpress-admin-email")"
readonly wp_admin_pass="$(get_attribute_value "wordpress-admin-password")"

readonly is_admin_node="$(get_attribute_value "is-admin-node" \
  | tr '[:upper:]' '[:lower:]')"

readonly gcs_bucket_name="$(get_attribute_value "bucket-name")"

chown -R www-data:www-data /var/www

# Update Apache max workers number:
function set_apache_max_workers() {
  local -r max_workers="$1"
  local -r mpm_config_file="/etc/apache2/mods-available/mpm_prefork.conf"

  if [[ ! -f "${mpm_config_file}" ]]; then
    echo "C2D: Config file for MPM module does not exist - skipping"
    return 0
  fi

  # Update MaxRequestWorkers
  sed -i "s/MaxRequestWorkers\s\+[0-9]\+\$/MaxRequestWorkers\t${max_workers}/" "${mpm_config_file}"

  # Update ServerLimit
  if grep -q ServerLimit $mpm_config_file; then
    sed -i "s/ServerLimit.*\$/ServerLimit\t\t${max_workers}/" "${mpm_config_file}"
  else
    local -r tab="$(echo $'\t')"
    sed -i "/MaxRequestWorkers\s\+${max_workers}\$/ a\
      \\\\tServerLimit\t\t${max_workers}" "${mpm_config_file}"
  fi

  service apache2 restart
}

readonly new_max_workers="$(( "$(nproc)" * 150 ))"
set_apache_max_workers "${new_max_workers}"

# Coordinate initial database installation:
if [[ "${is_admin_node}" == "true" ]]; then
  admin_waiter_path="$(get_attribute_value "admin-status-path")"
else
  # Wait until admin node is ready
  admin_waiter_name="$(get_attribute_value "admin-waiter-name")"
  wait_for_rtc_waiter_success "${runtime_config}" "${admin_waiter_name}" 600
fi

echo "C2D: Wait for the database connection to be available"

function validate_db_connection() {
  mysql -u wordpress \
    -p"${wordpress_password}" \
    -h "${database_ip}" \
    -D wordpress \
    -e "SELECT 1 = 1"
}

while ! validate_db_connection; do
  echo "C2D: Database connection not yet available..."
  sleep 3
done

echo "C2D: Set up service account"

# Set up service account
mkdir -p /opt/c2d/auth
readonly service_account="$(get_attribute_value "service-account-name")"
readonly service_account_key_base_64="$(get_attribute_value "service-account-key-base-64")"

readonly service_account_key="$(echo "${service_account_key_base_64}" \
  | base64 -d)"

readonly installWithMultisite="$(get_attribute_value "wordpress-enable-multisite" \
    | tr '[:upper:]' '[:lower:]')"

echo "${service_account_key}" > /opt/c2d/auth/sa_key.json

gcloud auth activate-service-account \
  "${service_account}" --key-file /opt/c2d/auth/sa_key.json

function wait_for_ip() {
  echo "Wait for IP address"
  wait_for_rtc_var "${runtime_config}" "ipaddress"
}

function install_wp_core() {
  readonly ipaddress="$(get_rtc_var_text "${runtime_config}" "ipaddress")"

  echo "C2D: WordPress - install core"

  sudo -u www-data wp core install \
    --url="${ipaddress}" \
    --title="WordPress HA on Google Cloud" \
    --admin_user=admin \
    --admin_password="${wp_admin_pass}" \
    --admin_email="${wp_admin_email}" \
    --path=/var/www/html/ \
    --skip-email
}

function install_wp_stateless() {
  echo "C2D: WordPress - install WP-Stateless"

  mv /opt/c2d/downloads/wp-stateless/ /var/www/html/wp-content/plugins/
  chown -R www-data:www-data /var/www/html/wp-content/plugins/
}

if gsutil -q stat gs://${gcs_bucket_name}/wp-app/wp-config.php; then
  echo "C2D: WordPress - pull bucket"

  /opt/c2d/downloads/gcs-pull-once.sh

else

  readonly wp_stateless_config="
  define('WP_STATELESS_MEDIA_MODE', 'stateless');
  define('WP_STATELESS_MEDIA_BODY_REWRITE', true);
  define('WP_STATELESS_MEDIA_BODY_REWRITE_TYPES', 'jpg jpeg png gif pdf');
  define('WP_STATELESS_MEDIA_BUCKET', '${gcs_bucket_name}');
  define('WP_STATELESS_MEDIA_ROOT_DIR', 'wp-media');
  define('WP_STATELESS_MEDIA_JSON_KEY', file_get_contents('/opt/c2d/auth/sa_key.json'));
  define('WP_STATELESS_MEDIA_CACHE_CONTROL', '');
  define('WP_STATELESS_MEDIA_DELETE_REMOTE', true);
  define('WP_STATELESS_MEDIA_CUSTOM_DOMAIN', '');
  define('WP_STATELESS_MEDIA_CACHE_BUSTING', true);"

  readonly wp_multisite_config="
  define('WP_ALLOW_MULTISITE', true);"

  if [[ "${installWithMultisite:-}" == "true" ]]; then

    echo "C2D: WordPress - create config with Multisite feature"

    sudo -u www-data wp config create \
      --dbname=wordpress \
      --dbuser=wordpress \
      --dbpass="${wordpress_password}" \
      --dbhost="${database_ip}" \
      --path=/var/www/html/ \
      --force \
      --extra-php <<<"${wp_stateless_config} ${wp_multisite_config}"

    wait_for_ip
    install_wp_core
    install_wp_stateless

    # Deactivate all plugins for Multisite feature
    sudo -u www-data wp plugin deactivate --all \
      --path=/var/www/html
  else

    echo "C2D: WordPress - create config"

    sudo -u www-data wp config create \
      --dbname=wordpress \
      --dbuser=wordpress \
      --dbpass="${wordpress_password}" \
      --dbhost="${database_ip}" \
      --path=/var/www/html/ \
      --force \
      --extra-php <<<"${wp_stateless_config}"

    wait_for_ip
    install_wp_core
    install_wp_stateless

    sudo -u www-data wp plugin activate wp-stateless \
    --path=/var/www/html

  fi
fi

if [[ "${is_admin_node}" == "true" ]]; then
  # Notify admin waiter about wordpress being installed
  set_rtc_var_text "${runtime_config}" \
    "${admin_waiter_path}/success/${hostname}" "SUCCESS"
fi

echo "C2D: Set up sync service"

# Set up GCS Sync service

if [[ "${is_admin_node}" == "true" ]]; then
  echo "Configuring GCS sync for ADMIN node..."
  rm /opt/c2d/downloads/gcs-pull.sh
  mv /opt/c2d/downloads/gcs-push.sh /opt/c2d/downloads/gcs-sync
elif [[ "${is_admin_node}" == "false" ]]; then
  echo "Configuring GCS sync for CONTENT node..."
  rm /opt/c2d/downloads/gcs-push.sh
  mv /opt/c2d/downloads/gcs-pull.sh /opt/c2d/downloads/gcs-sync
fi

systemctl enable gcs-sync
systemctl start gcs-sync

echo "C2D: Added and enabled gcs-sync service!"
